package com.ysu.concurrency;

import com.sun.xml.internal.ws.policy.EffectiveAlternativeSelector;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Vector;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

@Controller
@RestController
public class TestController {
    @RequestMapping("/test")
    public String test(){
        return "test";
    }
}

class TestPC{
    public static void main(String[] args) {
        Source source = new Source(0);
        new Thread(()->{
            for (int i = 0; i < 20; i++) {
                source.add();
            }
        },"P1").start();

        new Thread(()->{
            for (int i = 0; i < 20; i++) {
                source.add();
            }
        },"P2").start();

        new Thread(()->{
            for (int i = 0; i < 40; i++) {
                source.min();
            }
        },"C").start();

        List<Integer> vector = new Vector<>();
        List<Integer> list = new CopyOnWriteArrayList<>();
    }
}

class Source{

    private int num;
    private int max = 10;
    Lock lock = new ReentrantLock();
    Condition condition = lock.newCondition();

    Source(int num){
        this.num = num;
    }

    public void add(){
        lock.lock();
        try {
            while (this.num >= max ){
                try {
//                this.wait();
                    System.out.println(Thread.currentThread().getName() + "--------------await");
                    condition.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            this.num++;
            System.out.println(Thread.currentThread().getName() + "生产" + num);
            condition.signalAll();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }

    }

    public void min(){
        lock.lock();
        try {
            while (this.num == 0){
                try {
                    System.out.println(Thread.currentThread().getName() + "---------await");
                    condition.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            this.num--;
            System.out.println(Thread.currentThread().getName() + "消耗" + num);
            condition.signalAll();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }
}